"""通用接口的视图函数模块"""
import datetime
import json
import traceback

import pandas as pd
from es_pandas import es_pandas
from flask import request, send_file

from air_web.config.config import config
from air_web.data_platform import sql_engine
from air_web.web_flask.bll.commom_bll import CommonBll
from air_web.web_flask.bll.model_map import ModelMap
from air_web.web_flask.common.constants import (
    PAGE_NO,
    PAGE_SIZE,
    province_code,
)
from air_web.web_flask.common.tools import get_default_result
from air_web.web_flask.common.validator import (
    T_INT,
    T_LIST,
    T_STR,
    Fields,
    with_validator,
)
from air_web.web_flask.views.base_page import BasePage


class CommonPageValidationField:
    """通用接口字段验证类"""

    column_map_fields = [Fields("column", T_STR, must=True)]
    area_fields = [
        Fields("org_name", T_STR),
        Fields("org_no", T_INT),
        # Fields("org_level", T_INT, default=0),
        Fields("page_no", T_INT, default=PAGE_NO),
        Fields("page_size", T_INT, default=PAGE_SIZE),
    ]
    type_fields = [
        Fields("type_code_sort", T_INT),
        Fields("org_no", T_STR, default=province_code),
    ]
    cons_fields = [
        Fields("org_no", T_STR, default="99"),
        Fields("org_level", T_INT, must=True),
        Fields("type_id", T_INT),
        Fields("type_level", T_INT),
        Fields("cons_name", T_STR),
        Fields("type_code_sort", T_INT),
        Fields("is_monitor", T_INT),
    ]
    summary_fields = [
        Fields("sync_model", T_STR, default="increase"),
        Fields("es_index_name", T_STR),  # 增量时意义较大
    ]


class CommonPage(BasePage):
    @classmethod
    @with_validator(request, CommonPageValidationField.column_map_fields)
    def column_map(cls):
        args = request.validation_data
        result = ModelMap.get_all(**args)
        return cls.return_common_func(result)

    @classmethod
    @with_validator(request, CommonPageValidationField.area_fields)
    def org(cls):
        args = request.validation_data
        org_no = args["org_no"]
        # org_level = args["org_level"]
        name_tuple, result, level_result, org_level = CommonBll().get_org(
            **args
        )
        if org_level == 0:
            result.insert(
                0,
                {
                    "org_no": level_result.get("org_no"),
                    "org_name": level_result.get("org_name"),
                    "p_org_no": level_result.get("org_no"),
                    "org_level": level_result.get("org_level"),
                    "p_org_name": name_tuple[1],
                    "real_name": name_tuple[0],
                },
            )
        else:
            result.insert(
                0,
                {
                    "org_no": org_no,
                    "org_name": "全部供电公司",
                    "p_org_no": org_no,
                    "org_level": org_level,
                    "p_org_name": name_tuple[1],
                    "real_name": name_tuple[0],
                },
            )
        org_dict = {}

        for i in result:
            org_dict[i["org_no"]] = i

        return cls.return_common_func({"org_dict": org_dict})

    @classmethod
    @with_validator(request, CommonPageValidationField.type_fields)
    def type_code(cls):
        args = request.validation_data
        type_code_sort = args.get("type_code_sort")
        result = CommonBll().get_type_code(**args)
        return cls.return_common_func(result)

    @classmethod
    def industry_info(cls):
        result = CommonBll().get_industry_info()
        return cls.return_common_func(result)

    @classmethod
    @with_validator(request, CommonPageValidationField.cons_fields)
    def cons_search(cls):
        args = request.validation_data
        result = CommonBll().get_cons_info(**args)
        return cls.return_common_func(result)

    @classmethod
    # @with_validator(request, CommonPageValidationField.cons_fields)
    def low_type(cls):
        # args = request.validation_data
        result = CommonBll().get_low_type()
        return cls.return_common_func(result)

    @classmethod
    @with_validator(request, CommonPageValidationField.summary_fields)
    def summary(cls):
        args = request.validation_data

        def index_name():
            # 如果是全量，则遍历的索引是按月的全部
            # 如果是增量，则遍历的索引是传过来的名称
            pass

            # 触发计算，要做执行状态控制，启动、结束

    @classmethod
    def upload_weather(cls):
        file = request.files["file"]
        res = get_default_result()
        try:
            file_name = file.filename
            if "csv" not in file_name or file_name.split(".")[-1] != "csv":
                raise Exception("文件类型非 csv ,请参考模板")
            df = pd.read_csv(file, dtype={"region_code": str})
            if df.empty:
                raise Exception("没有数据需要导入")
            csv_columns = [
                "region_code",
                "datetime",
                "tmp",
                "rh",
                "wind_s",
                "wind_d",
                "pre",
                "prs",
            ]
            if set(csv_columns) - set(df.columns):
                raise Exception(
                    "缺少列:{}".format(set(csv_columns) - set(df.columns))
                )
            df = df[csv_columns]
            df.fillna(0, inplace=True)
            if len(df) == 0:
                raise Exception("文件为空，导入失败")
            df.drop_duplicates(inplace=True)
            ep = es_pandas(hosts=config["ES_HOST"])
            df["datetime"] = pd.to_datetime(df["datetime"])
            table_bame = config.get("ACLR_WEATHER_HOUR", "aclr_weather_hour")
            ep.to_es(df, table_bame)
            sql_engine.update_df_by_id(df, table_bame)
        except Exception as e:
            print(traceback.print_exc())
            res["status"] = 9
            res["msg"] = str(e)
        return json.dumps(res)

    @classmethod
    def download_weather_demo(cls):
        return send_file(
            "./air_web/web_flask/common/weather_demo.csv", as_attachment=True
        )

    @classmethod
    def finish_time(cls):
        result = CommonBll().get_finish_time()
        return cls.return_common_func(result)
